package com.iplant.aps.serviceimpl.utils.aps;

import com.alibaba.fastjson.JSON;
import com.iplant.aps.service.mesenum.APSShiftPeriod;
import com.iplant.aps.service.mesenum.BFCMessageType;
import com.iplant.aps.service.mesenum.BPMEventModule;
import com.iplant.aps.service.mesenum.FMCShiftLevel;
import com.iplant.aps.service.po.OutResult;
import com.iplant.aps.service.po.aps.APSBOMItem;
import com.iplant.aps.service.po.aps.APSBOMLog;
import com.iplant.aps.service.po.bfc.BFCMessage;
import com.iplant.aps.service.po.bms.BMSEmployee;
import com.iplant.aps.service.po.oms.OMSOrder;
import com.iplant.aps.service.po.sap.APSBomData;
import com.iplant.aps.service.po.sap.HEAD;
import com.iplant.aps.service.po.sap.INPUT2;
import com.iplant.aps.service.po.sap.ITEM;
import com.iplant.aps.service.po.sfc.SFCQualityLossBPM;
import com.iplant.aps.service.utils.Configuration;
import com.iplant.aps.service.utils.StringUtils;
import com.iplant.aps.serviceimpl.CoreServiceImpl;
import com.iplant.aps.serviceimpl.dao.aps.APSBOMItemDAO;
import com.iplant.aps.serviceimpl.dao.aps.APSBOMLogDAO;
import com.iplant.aps.serviceimpl.dao.sfc.SFCQualityLossBPMDAO;
import com.iplant.aps.serviceimpl.utils.MESServer;
import com.iplant.aps.shristool.CalendarDAO;
import org.apache.axis.client.Call;
import org.apache.axis.encoding.XMLType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.xml.namespace.QName;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class APSBOMUtils {
    private static final Logger logger = LoggerFactory.getLogger(APSBOMUtils.class);

    public APSBOMUtils() {
    }

    private static APSBOMUtils Instance;

    public static APSBOMUtils getInstance() {
        if (Instance == null)
            Instance = new APSBOMUtils();
        return Instance;
    }

    /**
     * 获取明细
     */
    public List<ITEM> GetITEM(List<APSBOMItem> wList) {
        List<ITEM> wResult = new ArrayList<>();
        try {
            SimpleDateFormat wDateFormat = new SimpleDateFormat("yyyyMMdd");
            SimpleDateFormat wTimeFormat = new SimpleDateFormat("HHmmss");

            for (APSBOMItem wAPSBOMItem : wList) {
                ITEM wItem = new ITEM();

                wItem.AEDAT = wDateFormat.format(wAPSBOMItem.EditTime.getTime());
                wItem.AENAM = "RFC_USER";
                wItem.AETIM = wTimeFormat.format(wAPSBOMItem.EditTime.getTime());
                wItem.BWTAR = wAPSBOMItem.AssessmentType;
                wItem.ERDAT = wDateFormat.format(wAPSBOMItem.EditTime.getTime());
                wItem.ERNAM = "RFC_USER";
                wItem.ERTIM = wTimeFormat.format(wAPSBOMItem.EditTime.getTime());
                wItem.GRPNR = "";
                wItem.ID = wAPSBOMItem.OrderID;
                wItem.ITEMID = wAPSBOMItem.OrderNum;
                wItem.KTEXT = wAPSBOMItem.TextCode;
                wItem.KTTXT = StringUtils.Format("{0}  {1}", APSConstans.GetFPCPart(wAPSBOMItem.PartID).Code,
                        wAPSBOMItem.PartPointName);
                wItem.MATNR = wAPSBOMItem.MaterialNo;
                // wItem.MEINS = wAPSBOMItem.UnitText;
                wItem.MEINS = APSConstans.GetCFGUnit(wAPSBOMItem.UnitID).Name;
                wItem.MENGE = String.valueOf(wAPSBOMItem.Number);
                wItem.RGEKZ = "";
                wItem.USR00 = APSConstans.GetFPCPart(wAPSBOMItem.PartID).Code;
                wItem.XFJJ = wAPSBOMItem.RepairCoreIdentification;
                wItem.ZBHOH = wAPSBOMItem.ReplaceType <= 0 ? "" : String.valueOf(wAPSBOMItem.ReplaceType);
                wItem.ZCJXC = wAPSBOMItem.DisassyType > 0 ? "X" : "";
                wItem.ZDELE = wAPSBOMItem.DeleteID;
                wItem.ZDRHH = wAPSBOMItem.DingrongGroup;
                wItem.ZFLAGFJ = wAPSBOMItem.AccessoryLogo;
                wItem.ZFLAGJXJ = wAPSBOMItem.RepairPartClass;
                wItem.ZFLAGKGL = wAPSBOMItem.CustomerMaterial > 0 ? "X" : "";
                wItem.ZLGORT = String.valueOf(wAPSBOMItem.StockID);
                wItem.ZLLSL = String.valueOf(wAPSBOMItem.PickingQuantity);
                wItem.ZREMARK = wAPSBOMItem.Remark;
                wItem.ZSCXC = wAPSBOMItem.OverLine > 0 ? "X" : "";
                wItem.ZSFHH = wAPSBOMItem.PartChange > 0 ? "X" : "";
                wItem.ZWTDW = wAPSBOMItem.DisassyType > 0 ? "X" : "";
                wItem.ZYCYZ = wAPSBOMItem.OriginalType > 0 ? "X" : "";
                wItem.ZZDHL = String.valueOf(wAPSBOMItem.EvenExchangeRate);
                wItem.ZZFC = wAPSBOMItem.ReceiveDepart;
                wItem.ZZLDL = wAPSBOMItem.QTType <= 0 ? ""
                        : wAPSBOMItem.QTType == 1 ? "001"
                        : wAPSBOMItem.QTType == 2 ? "002"
                        : wAPSBOMItem.QTType == 3 ? "003" : wAPSBOMItem.QTType == 4 ? "004" : "";
                wItem.ZZLXL = wAPSBOMItem.QTItemType <= 0 ? ""
                        : wAPSBOMItem.QTItemType == 1 ? "01"
                        : wAPSBOMItem.QTItemType == 2 ? "02"
                        : wAPSBOMItem.QTItemType == 3 ? "03"
                        : wAPSBOMItem.QTItemType == 4 ? "04"
                        : wAPSBOMItem.QTItemType == 5 ? "05" : "";
                wItem.ZZZBZ = wAPSBOMItem.Remark;
                wItem.ZZZWW = wAPSBOMItem.OutsourceType <= 0 ? "" : String.valueOf(wAPSBOMItem.OutsourceType);

                wResult.add(wItem);
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    /**
     * 获取表头
     */
    public HEAD GetHead(APSBOMItem wAPSBOMItem) {
        HEAD wResult = new HEAD();
        try {
            SimpleDateFormat wDateFormat = new SimpleDateFormat("yyyyMMdd");
            SimpleDateFormat wTimeFormat = new SimpleDateFormat("HHmmss");

            wResult.AEDAT = wDateFormat.format(wAPSBOMItem.EditTime.getTime());
            wResult.AENAM = "RFC_USER";
            wResult.AETIM = wTimeFormat.format(wAPSBOMItem.EditTime.getTime());
            wResult.ARBPL = wAPSBOMItem.WorkCenter;
            wResult.ERDAT = wDateFormat.format(wAPSBOMItem.EditTime.getTime());
            wResult.ERNAM = "RFC_USER";
            wResult.ERTIM = wTimeFormat.format(wAPSBOMItem.EditTime.getTime());
            wResult.ID = wAPSBOMItem.OrderID;
            wResult.KTEXT = wAPSBOMItem.TextCode;
            wResult.MAT_PSPNR = wAPSBOMItem.WBSNo;
            wResult.WERKS = String.valueOf(wAPSBOMItem.FactoryID);
            wResult.ZCHEX = wAPSBOMItem.ProductNo;
            wResult.ZDELE = "";
            wResult.ZJDXX = wAPSBOMItem.CustomerCode;
            wResult.ZSCLX = String.valueOf(wAPSBOMItem.BOMType);
            wResult.ZXIUC = wAPSBOMItem.LineName.replace("C", "");
            wResult.ZZFC = wAPSBOMItem.ReceiveDepart;
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    /**
     * 检查台车BOM
     */
    public String CheckAPSBOM(List<APSBOMItem> wMSSBOMItemList, OMSOrder wOrder) {
        String wResult = "";
        try {
            // ①BOM类型必须是在生产类型表(ZPPSCLX-ZSCLX中维护过的值)，目前只有3个值：1新造 2检修 9计划外;
            if (wMSSBOMItemList.stream().anyMatch(p -> p.BOMType != 1 && p.BOMType != 2 && p.BOMType != 9)) {
                wResult = StringUtils.Format(
                        "提示：【{0}】创建台车BOM失败。BOM类型必须是在生产类型表(ZPPSCLX-ZSCLX中维护过的值)，目前只有3个值：1新造 2检修 9计划外;", wOrder.PartNo);
                return wResult;
            }
            // ②车型数据必须是在车型配置表(TCJ1T-PRATX)中维护过的值，例：HXD1C;
            if (wMSSBOMItemList.stream().anyMatch(p -> p.ProductID <= 0)) {
                wResult = StringUtils.Format("提示：【{0}】创建台车BOM失败。车型数据必须是在车型配置表(TCJ1T-PRATX)中维护过的值，例：HXD1C",
                        wOrder.PartNo);
                return wResult;
            }
            // ③修程：当BOM类型为2时，修程只允许5/6，当BOM类型为1时修程只允许为空白；当BOM类型为9时，允许5/6、空白。
            if (wMSSBOMItemList.stream().anyMatch(
                    p -> (p.BOMType == 2 && p.LineID != 1 && p.LineID != 2) || (p.BOMType == 1 && p.LineID != 0)
                            || (p.BOMType == 9 && p.LineID != 1 && p.LineID != 2 && p.LineID != 0))) {
                wResult = StringUtils.Format(
                        "提示：【{0}】创建台车BOM失败。当BOM类型为2时，修程只允许5/6，当BOM类型为1时修程只允许为空白；当BOM类型为9时，允许5/6、空白。", wOrder.PartNo);
                return wResult;
            }
            // ④局段信息：必须是在局段表(ZPMJD-ZJDXX)中维护过的值，例：NN(南宁)；
            if (wMSSBOMItemList.stream().anyMatch(p -> p.CustomerID <= 0)) {
                wResult = StringUtils.Format("提示：【{0}】创建台车BOM失败。局段信息：必须是在局段表(ZPMJD-ZJDXX)中维护过的值，例：NN(南宁)；",
                        wOrder.PartNo);
                return wResult;
            }
            // ⑤工厂：检查工厂表(T001W-WERKS),目前只有1900；
            if (wMSSBOMItemList.stream().anyMatch(p -> p.FactoryID != 1900)) {
                wResult = StringUtils.Format("提示：【{0}】创建台车BOM失败。工厂：检查工厂表(T001W-WERKS),目前只有1900；", wOrder.PartNo);
                return wResult;
            }
            // ⑥WBS元素：第9位必须是P，必须已经在项目中维护过的WBS(PRPS-PSPNR);
            if (wMSSBOMItemList.stream().anyMatch(p -> p.WBSNo.length() < 9 || p.WBSNo.charAt(8) != 'P')) {
                wResult = StringUtils.Format("提示：【{0}】创建台车BOM失败。WBS元素：第9位必须是P，必须已经在项目中维护过的WBS(PRPS-PSPNR);",
                        wOrder.PartNo);
                return wResult;
            }
            // ⑦工位：必须在工位表清单中(ZPPTW-USR00)已经维护；
            if (wMSSBOMItemList.stream().anyMatch(p -> p.PartID <= 0)) {
                wResult = StringUtils.Format("提示：【{0}】创建台车BOM失败。工位：必须在工位表清单中(ZPPTW-USR00)已经维护；", wOrder.PartNo);
                return wResult;
            }
            // ⑧工序：工序描述必须是在ZPM1011工序清单中维护；
            if (wMSSBOMItemList.stream().anyMatch(p -> p.PartPointID <= 0)) {
                wResult = StringUtils.Format("提示：【{0}】创建台车BOM失败。工序：工序描述必须是在ZPM1011工序清单中维护；", wOrder.PartNo);
                return wResult;
            }
            // ⑨物料编码：和工厂一起检查表(MARA-MEINS)
            if (wMSSBOMItemList.stream().anyMatch(p -> p.MaterialID <= 0)) {
                wResult = StringUtils.Format("提示：【{0}】创建台车BOM失败。物料编码：和工厂一起检查表(MARA-MEINS)。", wOrder.PartNo);
                return wResult;
            }
            // ⑩物料名称：不检查；
            // ①单位：检查与物料的基本单位一致(MARA-MEINS)；
            if (wMSSBOMItemList.stream().anyMatch(p -> p.UnitID <= 0)) {
                wResult = StringUtils.Format("提示：【{0}】创建台车BOM失败。单位：检查与物料的基本单位一致(MARA-MEINS)；", wOrder.PartNo);
                return wResult;
            }
            // ②评估类型：只允许的值：修复旧件、可用旧件、常规新件、高价互换件；
            if (wMSSBOMItemList.stream()
                    .anyMatch(p -> !p.AssessmentType.equals("修复旧件") && !p.AssessmentType.equals("可用旧件")
                            && !p.AssessmentType.equals("常规新件") && !p.AssessmentType.equals("高价互换件"))) {
                wResult = StringUtils.Format("提示：【{0}】创建台车BOM失败。评估类型：只允许的值：修复旧件、可用旧件、常规新件、高价互换件", wOrder.PartNo);
                return wResult;
            }
            // ③是否互换件：只允许X或空白；
            if (wMSSBOMItemList.stream().anyMatch(p -> p.PartChange != 0 && p.PartChange != 1)) {
                wResult = StringUtils.Format("提示：【{0}】创建台车BOM失败。是否互换件：只允许X或空白；", wOrder.PartNo);
                return wResult;
            }
            // ④是否超修程：只允许X或空白；
            if (wMSSBOMItemList.stream().anyMatch(p -> p.OverLine != 0 && p.OverLine != 1)) {
                wResult = StringUtils.Format("提示：【{0}】创建台车BOM失败。是否超修程：只允许X或空白；", wOrder.PartNo);
                return wResult;
            }
            // ⑤领料部门：只允许0001；
            if (wMSSBOMItemList.stream().anyMatch(p -> !p.ReceiveDepart.equals("0001"))) {
                wResult = StringUtils.Format("提示：【{0}】创建台车BOM失败。领料部门：只允许0001；", wOrder.PartNo);
                return wResult;
            }
            // ⑥仓库号：BOM类型为1时固定值1100，BOM类型为2时固定值1200，BOM类型为9时，允许1100和1200；
            if (wMSSBOMItemList.stream()
                    .anyMatch(p -> (p.BOMType == 1 && p.StockID != 1100) || (p.BOMType == 2 && p.StockID != 1200)
                            || (p.BOMType == 9 && p.StockID != 1100 && p.StockID != 1200))) {
                wResult = StringUtils.Format(
                        "提示：【{0}】创建台车BOM失败。仓库号：BOM类型为1时固定值1100，BOM类型为2时固定值1200，BOM类型为9时，允许1100和1200；", wOrder.PartNo);
                return wResult;
            }
            // ⑦客供料与原拆原装要求，两个字段不能同时有值；
            if (wMSSBOMItemList.stream().anyMatch(p -> p.CustomerMaterial > 0 && p.OriginalType > 0)) {
                wResult = StringUtils.Format("提示：【{0}】创建台车BOM失败。客供料与原拆原装要求，两个字段不能同时有值；", wOrder.PartNo);
                return wResult;
            }
            // ⑧台车BOM中的组件用量不能为0，总数量不能大于标准BOM的用量；
            if (wMSSBOMItemList.stream().anyMatch(p -> p.Number <= 0)) {
                wResult = StringUtils.Format("提示：【{0}】创建台车BOM失败。台车BOM【{1}】中的组件用量不能为0，总数量不能大于标准BOM的用量；", wOrder.PartNo,
                        wMSSBOMItemList.stream().filter(p -> p.Number <= 0).findFirst().get().MaterialNo);
                return wResult;
            }
            // ⑨台车BOM中的行项目必须在标准BOM中能够找到；
            // ⑩已完工车辆不允许更改台车BOM。台车WBS标识完工时，对应的台车BOM保存时报错“已完工车辆不允许更改WBS_BOM”.
            if (wOrder.Status >= 5) {
                wResult = StringUtils.Format("提示：【{0}】创建台车BOM失败。已完工车辆不允许更改WBS_BOM", wOrder.PartNo);
                return wResult;
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }


    /**
     * 将台车BOM发送给SAP
     */
    public String SendToSAPByQualityLoss(BMSEmployee wLoginUser, String wJson, String wWBSNo, int wQualityLossID,
                                          OMSOrder wOrder,
                                          int wMode, List<Integer> wAPSBOMIDList) {
        String wResult = "";
        try {
            String wEndPoint = APSUtils.getInstance().GetSAPEndpoint();
            org.apache.axis.client.Service wService = new org.apache.axis.client.Service();
            Call wCall = (Call) wService.createCall();

            wCall.setUsername(APSUtils.getInstance().GetSAPUser());
            wCall.setPassword(APSUtils.getInstance().GetSAPPassword());

            wCall.setTargetEndpointAddress(wEndPoint);
            wCall.setOperationName(new QName("urn:sap-com:document:sap:rfc:functions", "ZIF_MES_INPUT_001"));// 调用的方法名
            wCall.addParameter("INPUT1", XMLType.XSD_STRING, javax.xml.rpc.ParameterMode.IN);
            wCall.addParameter("INPUT2", XMLType.XSD_STRING, javax.xml.rpc.ParameterMode.IN);
            wCall.setReturnType(XMLType.XSD_STRING); // 返回值类型：String

            String wReturn = (String) wCall.invoke(new Object[]{"01", wJson});// 远程调用
            logger.info(wWBSNo + "::" + wReturn);

            CalendarDAO.getInstance().WriteLogFile(wJson + "::" + wReturn, "台车bom", wOrder, "");

            wResult = wReturn;

            if (wQualityLossID > 0) {
                ExecutorService wES = Executors.newFixedThreadPool(1);
                wES.submit(() -> UpdateSFCBOMTaskSAPStatusByQualityLoss(wLoginUser, wReturn, wQualityLossID));
                wES.shutdown();
            }

            if (wMode == 1) {
                // 发送创建台车bom的消息
                SendAPSBOMMessage(wLoginUser, wResult, wOrder);
            }

            if (wAPSBOMIDList != null && wAPSBOMIDList.size() > 0) {
                String wMsg = wResult;
                ExecutorService wES = Executors.newFixedThreadPool(1);
                wES.submit(() -> UpdateAPSBOMMsg(wLoginUser, wAPSBOMIDList, wMsg));
                wES.shutdown();
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }


    /**
     * 维护偶换件的推送SAP状态
     */
    public void UpdateSFCBOMTaskSAPStatusByQualityLoss(BMSEmployee wLoginUser, String wMsg, int wQualityLossID) {
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            SFCQualityLossBPM wTask = (SFCQualityLossBPM) SFCQualityLossBPMDAO.getInstance().BPM_GetTaskInfo(wLoginUser,
                    wQualityLossID, "",
                    wErrorCode);
            if (!StringUtils.isEmpty(wMsg)) {
                if (wMsg.contains("失败") || wMsg.contains("E")) {
                    wTask.SAPStatus = 2;
                    wTask.SAPStatusText = wMsg;
                    SFCQualityLossBPMDAO.getInstance().Update(wLoginUser, wTask, wErrorCode);

                    // ①发送通知消息给黄刚，通知他创建工序。
                    SendMessageToTechToCreateStep(wLoginUser, wTask.PartNo, wMsg, wTask.ID);
                } else if (wMsg.contains("S")) {
                    wTask.SAPStatus = 1;
                    wTask.SAPStatusText = "推送成功";
                    SFCQualityLossBPMDAO.getInstance().Update(wLoginUser, wTask, wErrorCode);
                }
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 发送通知消息给工艺(黄刚),通知他及时创建工序
     */
    public void SendMessageToTechToCreateStep(BMSEmployee wLoginUser, String partNo, String wMsg, int wTaskID) {
        try {
            String wUsers = Configuration.readConfigString("bomUser", "config/config");
            String[] wStrs = wUsers.split(",");

            List<BFCMessage> wBFCMessageList = new ArrayList<>();
            BFCMessage wMessage = null;
            int wShiftID = MESServer.MES_QueryShiftID(wLoginUser.CompanyID, Calendar.getInstance(), APSShiftPeriod.Day,
                    FMCShiftLevel.Day, 0);
            for (String wUserStr : wStrs) {
                int wUserID = Integer.parseInt(wUserStr);
                // 发送任务消息到人员
                wMessage = new BFCMessage();
                wMessage.Active = 0;
                wMessage.CompanyID = 0;
                wMessage.CreateTime = Calendar.getInstance();
                wMessage.EditTime = Calendar.getInstance();
                wMessage.ID = 0;
                wMessage.MessageID = wTaskID;
                wMessage.Title = StringUtils.Format("{0} 创建失败", BPMEventModule.APSBOMError.getLable());
                wMessage.MessageText = StringUtils.Format("【{0}】{1}", partNo, wMsg);
                wMessage.ModuleID = BPMEventModule.APSBOMError.getValue();
                wMessage.ResponsorID = wUserID;
                wMessage.ShiftID = wShiftID;
                wMessage.StationID = 0;
                wMessage.Type = BFCMessageType.Notify.getValue();
                wBFCMessageList.add(wMessage);
            }
            CoreServiceImpl.getInstance().BFC_UpdateMessageList(wLoginUser, wBFCMessageList);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }


    /**
     * 发送消息通知(创建台车bom成功与否)
     */
    public void SendAPSBOMMessage(BMSEmployee wLoginUser, String wMsg, OMSOrder wOrder) {
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            int wStatus = 0;
            if (wMsg.contains("失败") || wMsg.contains("E")) {
                wStatus = 2;
            } else if (wMsg.contains("成功")) {
                wStatus = 1;

                List<APSBOMLog> wHisList = APSBOMLogDAO.getInstance().SelectList(wLoginUser, -1, -1, -1, -1, wOrder.ID,
                        2, null, null, wErrorCode);
                for (APSBOMLog wAPSBOMLog : wHisList) {
                    wAPSBOMLog.Status = 3;
                    APSBOMLogDAO.getInstance().Update(wLoginUser, wAPSBOMLog, wErrorCode);
                }
            }

            APSBOMLog wLog = new APSBOMLog(0, wOrder.ProductID, wOrder.ProductNo, wOrder.LineID, wOrder.LineName,
                    wOrder.CustomerID, wOrder.Customer, wOrder.ID, wOrder.PartNo, wOrder.OrderNo, wStatus, wMsg,
                    Calendar.getInstance());
            wLog.BOMID = wOrder.BOMID;
            int wMessageID = APSBOMLogDAO.getInstance().Update(wLoginUser, wLog, wErrorCode);

            // 此处推送消息，告知为何创建台车bom失败
            List<BFCMessage> wBFCMessageList = new ArrayList<>();
            BFCMessage wMessage = null;
            int wShiftID = MESServer.MES_QueryShiftID(wLoginUser.CompanyID, Calendar.getInstance(), APSShiftPeriod.Day,
                    FMCShiftLevel.Day, 0);

            String wBomUser = Configuration.readConfigString("bomUser", "config/config");
            String[] wUserList = wBomUser.split(",");
            for (String wUserIDStr : wUserList) {
                int wUserID = StringUtils.parseInt(wUserIDStr);

                // 发送任务消息到人员
                wMessage = new BFCMessage();
                wMessage.Active = 0;
                wMessage.CompanyID = 0;
                wMessage.CreateTime = Calendar.getInstance();
                wMessage.EditTime = Calendar.getInstance();
                wMessage.ID = 0;
                wMessage.MessageID = 0;
                wMessage.Title = StringUtils.Format("{0} {1}", BPMEventModule.APSBOMCreateNotify.getLable(), wShiftID);

                if (wStatus == 1) {
                    wMessage.MessageText = StringUtils.Format("【{0}】{1}", wOrder.PartNo, wMsg);
                } else if (wStatus == 2) {
                    wMessage.MessageText = StringUtils.Format("【{0}】创建台车BOM失败，请查看失败详情，并及时处理。", wOrder.PartNo);
                } else {
                    wMessage.MessageText = StringUtils.Format("【{0}】{1}", wOrder.PartNo, wMsg);
                }

                wMessage.ModuleID = BPMEventModule.APSBOMCreateNotify.getValue();
                wMessage.MessageID = wMessageID;
                wMessage.ResponsorID = wUserID;
                wMessage.ShiftID = wShiftID;
                wMessage.StationID = 0;
                wMessage.Type = BFCMessageType.Notify.getValue();
                wBFCMessageList.add(wMessage);
            }

            CoreServiceImpl.getInstance().BFC_UpdateMessageList(wLoginUser, wBFCMessageList);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 更新台车BOM推送状态
     */
    public void UpdateAPSBOMMsg(BMSEmployee wLoginUser, List<Integer> wAPSBOMIDList, String wResult) {
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            if (wResult.contains("E")) {
                for (int wID : wAPSBOMIDList) {
                    APSBOMItem wItem = APSBOMItemDAO.getInstance().APS_QueryBOMItemByID(wLoginUser, wID, wErrorCode);
                    if (wItem == null || wItem.ID <= 0) {
                        continue;
                    }
                    wItem.SAPStatus = 2;
                    wItem.SAPMsg = wResult;
                    APSBOMItemDAO.getInstance().APS_UpdateBOMItem(wLoginUser, wItem, wErrorCode);
                }
            } else if (wResult.contains("成功")) {
                for (int wID : wAPSBOMIDList) {
                    APSBOMItem wItem = APSBOMItemDAO.getInstance().APS_QueryBOMItemByID(wLoginUser, wID, wErrorCode);
                    if (wItem == null || wItem.ID <= 0) {
                        continue;
                    }
                    wItem.SAPStatus = 1;
                    wItem.SAPMsg = "";
                    APSBOMItemDAO.getInstance().APS_UpdateBOMItem(wLoginUser, wItem, wErrorCode);
                }
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 将台车bom转换为SAP需要的json字符串
     */
    public String ChangeToJson(List<APSBOMItem> wList, String wFlag) {
        String wResult = "";
        try {
            if (wList == null || wList.size() <= 0) {
                return wResult;
            }

            APSBomData wAPSBomData = new APSBomData();
            wAPSBomData.INPUT1 = "01";

            INPUT2 wINPUT2 = new INPUT2();
            wINPUT2.MODE = wFlag;
            wINPUT2.HEAD = APSBOMUtils.getInstance().GetHead(wList.get(0));
            wINPUT2.ITEM = APSBOMUtils.getInstance().GetITEM(wList);
            wAPSBomData.INPUT2 = wINPUT2;

            wResult = JSON.toJSONString(wAPSBomData.INPUT2);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }
}
